/*
    <one line to give the library's name and an idea of what it does.>
    Copyright (C) 2015  <copyright holder> <email>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/


#include "serial.h"

serial::serial(string dev_file)
{
	device_file = dev_file;
}

serial::~serial()
{
}

void serial::serial_open()
{
	serial_fd = open(device_file.c_str(),O_RDWR|O_NOCTTY|O_NDELAY);
	if(serial_fd < 0)
	{
		perror("Fail to open serial file\n");  
		exit(EXIT_FAILURE);  
	}
}

void serial::serial_colse()
{
	close(serial_fd);
}
void serial::serial_seting(int speed,int data_bits,char event,int stop_bit)
{
	bzero(&serial_property,sizeof(serial_property));   //清0 serial_property
	//设置字符的大小
	serial_property.c_cflag |= CLOCAL | CREAD;
	serial_property.c_cflag &= ~CSIZE;
	
	//设置数据长度
	switch(data_bits)
	{
		case 5:
			serial_property.c_cflag |= CS5;
			break;
		case 6:
			serial_property.c_cflag |= CS6;
			break;
		case 7:
			serial_property.c_cflag |= CS7;
			break;
		case 8:
			serial_property.c_cflag |= CS8;
			break;
		default:
			serial_property.c_cflag |= CS8;   //默认为8位数据位
	}
//-----------------------------------------------------------------//
	//设置奇偶校验位
	switch(event)
	{
		case 'O':        //奇校验
			serial_property.c_cflag |= PARENB;
			serial_property.c_cflag |= PARODD;
			serial_property.c_cflag |= (INPCK | ISTRIP);
			break;
		case 'E':        //偶校验
			serial_property.c_cflag |= PARENB;
			serial_property.c_cflag |= ~PARODD;
			serial_property.c_cflag |= (INPCK | ISTRIP);
			break;
		case 'N':        //无校验
			serial_property.c_cflag &= ~PARENB;
			break;
		//-----------------------------------//
		case 'o':
			serial_property.c_cflag |= PARENB;
			serial_property.c_cflag |= PARODD;
			serial_property.c_cflag |= (INPCK | ISTRIP);			
			break;
		case 'e':
			serial_property.c_cflag |= PARENB;
			serial_property.c_cflag |= ~PARODD;
			serial_property.c_cflag |= (INPCK | ISTRIP);
			break;
		case 'n':
			serial_property.c_cflag &= ~PARENB;
			break;
		default:
			serial_property.c_cflag &= ~PARENB;      //默认是无校验
			break;
	}
//-----------------------------------------------------------------//
	//设置数据传输波特率
	switch(speed)
	{
		case 2400:
			cfsetispeed(&serial_property,B2400);
			cfsetospeed(&serial_property,B2400);
			break;
		case 4800:
			cfsetispeed(&serial_property,B4800);
			cfsetospeed(&serial_property,B4800);
			break;
		case 9600:
			cfsetispeed(&serial_property,B9600);
			cfsetospeed(&serial_property,B9600);
			break;
		case 19200:
			cfsetispeed(&serial_property,B19200);
			cfsetospeed(&serial_property,B19200);
			break;
		case 38400:
			cfsetispeed(&serial_property,B38400);
			cfsetospeed(&serial_property,B38400);
			break;
		case 57600:
			cfsetispeed(&serial_property,B57600);
			cfsetospeed(&serial_property,B57600);
			break;
		case 115200:
			cfsetispeed(&serial_property,B115200);
			cfsetospeed(&serial_property,B115200);
			break;
		case 230400:
			cfsetispeed(&serial_property,B230400);
			cfsetospeed(&serial_property,B230400);
			break;
		case 460800:
			cfsetispeed(&serial_property,B460800);
			cfsetospeed(&serial_property,B460800);
			break;
		default:
			cfsetispeed(&serial_property,B115200);
			cfsetospeed(&serial_property,B115200);
			break;
	}
//-----------------------------------------------------------------//
	//设置停止位
	if(stop_bit == 1)
	{
		serial_property.c_cflag |= ~CSTOPB;
	}
	else if(stop_bit == 2)
	{
		serial_property.c_cflag |= CSTOPB;
	}
//-----------------------------------------------------------------//
	//设置等待时间和最小接收字符
	serial_property.c_cc[VTIME] = 0;
	serial_property.c_cc[VMIN] = 0;
//-----------------------------------------------------------------//
	//处理未接收到的字符
	tcflush(serial_fd,TCIFLUSH);
	
//-----------------------------------------------------------------//
	//激活新的配置
	if((tcsetattr(serial_fd,TCSANOW,&serial_property)) != 0)
	{
		perror("Serial set Error!\n");
		exit(EXIT_FAILURE);
	}
}
void serial::serial_send(string str)
{
    write(serial_fd,str.c_str(),str.length());//实际写入的长度  
}
void serial::serial_receive()
{

}
#if 0
int main()
{
	int i = 0;
	serial t("/dev/ttySAC0");
	t.serial_open();
	//int speed,int data_bits,char event,int stop_bit)
	t.serial_seting(9600,8,'N',1);
	sleep(1);

	
	while(1)
	{
		t.serial_send("hello\r\n");
		sleep(1);
		printf("i = %d\n",i++);
	}
	
	return 0;
}
#endif